package Transformation;

import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.List;

public class XSLManager {
	
	public boolean createXSL(WsdlTransformation tran, String newFilePath) {

		boolean error = false;
		FileWriter file = null;
		try {
			file = new FileWriter(newFilePath);
			PrintWriter pw = new PrintWriter(file);

			/*** Begin new xsl ***/

			pw.print(XSLStartTemplate());
			List<OperationChange> operations = tran.getOperations();
			for (OperationChange operation: operations){
				OperationChange.Modification OperationModificationType = operation.getModificationTypeName();
				switch (OperationModificationType){
				case RENAME:
					pw.print(getRenameFunctionTemplate(operation.getName(),operation.getNewName()));
					parameterChanges(operation,pw);
					break;
				case DELETE:
					pw.print(getDeleteFunctionTemplate(operation.getName()));
					break;
				case ONLYPARAMETERCHANGES:
					parameterChanges(operation,pw);
					break;
				}
			}
			
			pw.print(XSLEndTemplate());
			
			/*** End new xsl ***/

		} catch (Exception ex) {
			error = true;
			ex.printStackTrace();
		} finally {
			try {
				if (null != file) {
					file.close();
				}
			} catch (Exception ex) {
				error = true;
				ex.printStackTrace();
			}
		}

		return error;
	}
	
	
	
	/*** AUXILIARY FUNCTIONS ***/
	
	private void parameterChanges(OperationChange operation, PrintWriter pw) {
		List<ParameterChange> parameterChanges = operation.getParameterChanges();
		for (ParameterChange parameterChange : parameterChanges) {
			ParameterChange.Modification parameterModificationType = parameterChange.getModificationType();
			switch (parameterModificationType) {
			case NEW:
				if (parameterChange.getPreviousNameNode()!= null){
					pw.print(getAddParameterTemplate(parameterChange.getPreviousNameNode(),	parameterChange.getParametersToInsert()));
				}else{
					pw.print(getAddFirstParameterTemplate(operation.getName(),parameterChange.getParametersToInsert()));
				}
				break;
			case RENAME:
				pw.print(getRenameParameterTemplate(parameterChange.getName(),parameterChange.getNewName()));
				break;
			case DELETE:
				pw.print(getDeleteParameterTemplate(parameterChange.getName()));
				break;
			}
		}
	}
	
	private String XSLStartTemplate() {
		String template = "<?xml version=\"1.0\"?>\n<xsl:stylesheet version=\"1.0\"\n\txmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" \n\txmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n\txmlns:tes=\"http://testing.ws.adapative.esb.uy.edu.fing.org/\">\n\n\t<xsl:strip-space elements=\"*\" />\n\t\t\n\t<xsl:output method=\"xml\" media-type=\"application/xhtml+xml\" omit-xml-declaration=\"yes\" encoding=\"utf-8\" indent=\"yes\" />\n\t\n\t<xsl:template match=\"/\">\t\t\t\t\n\t\t<xsl:apply-templates select=\"soapenv:Envelope\" />\n\t</xsl:template>\n\n\t<!-- Process Envelope Object -->\n\t<xsl:template match=\"soapenv:Envelope\">\t\n\t\t<xsl:copy>\n\t\t\t<xsl:apply-templates select=\"soapenv:Header\" />\t\t\n\t\t\t<xsl:apply-templates select=\"soapenv:Body\" />\t\n\t\t</xsl:copy>\n\t</xsl:template>\n\t\n\t<!-- Process Header Object -->\n\t<xsl:template match=\"soapenv:Header\">\n\t \t<xsl:copy> \n\t \t\t <xsl:apply-templates select=\"@*|node()\"/>\n\t \t</xsl:copy>\n\t</xsl:template>\n\t\n\t<!-- Process Body Object -->\n\t<xsl:template match=\"soapenv:Body\">\n\t\t<xsl:copy>\n\t\t\t<xsl:call-template name=\"funtionName\" />\n\t \t</xsl:copy>\n\t</xsl:template>\n\t\n\t<!-- Process Function Object -->\n\t<xsl:template name=\"funtionName\">\n\t\t<xsl:apply-templates select=\"@*|node()\"/>\n\t</xsl:template>\n\t\n\t<!-- ###################################### AUXILIARY FUNCTIONS ###################################### -->\n\t\n\t<!-- Copy Object Recursive -->\n\t<xsl:template match=\"@*|node()\">\n\t\t<xsl:copy>\n\t\t\t<xsl:apply-templates select=\"@*|node()\"/>\n\t\t</xsl:copy>\n\t</xsl:template>\n\t\n\t<!-- ###################################### PROCESS CHANGE IN WSDL ###################################### -->\n";
		return template;
	}
	
	
	private String getRenameFunctionTemplate(String oldFunctionName, String newFunctionName) {
		String renameFunctionTemplate = "\n\t<!-- Process Rename in Function Name -->\n\t<xsl:template match=\"tes:"
				+ oldFunctionName
				+ "\">\n\t\t<tes:"
				+ newFunctionName
				+ ">\n\t\t\t<xsl:apply-templates select=\"@*|node()\"/>\n\t\t</tes:"
				+ newFunctionName
				+ ">\n\t</xsl:template>\n";
		return renameFunctionTemplate;
	}

	
	private String getRenameParameterTemplate(String oldParameterName,String newParameterName) {
		String renameParameterTemplate = "\n\t<!-- Process Rename in Parameters Names -->\n\t<xsl:template match=\""
				+ oldParameterName
				+ "\">\n\t\t<"
				+ newParameterName
				+ ">\n\t\t\t<xsl:apply-templates select=\"@*|node()\"/>\n\t\t</"
				+ newParameterName 
				+ ">\n\t</xsl:template>\n";
		return renameParameterTemplate;
	}

	private String getAddParameterTemplate(String previousParameter, List<Parameter> newParameters) {
		String addParameterTemplate = "\n\t<!-- Process Add Parameter -->\n\t<xsl:template match=\""
				+ previousParameter
				+ "\">\n\t  \t<xsl:copy>\n\t    \t<xsl:apply-templates select=\"@*|node()\"/>\n  \t\t</xsl:copy>" ;	
				String parameters = "";
				for (Parameter newParameter: newParameters){
					parameters += "\n  \t\t<" + newParameter.getName() + ">"+ newParameter.getValue() +"</"+ newParameter.getName() + ">";
				}
				addParameterTemplate = addParameterTemplate + parameters + "\n\t</xsl:template>\n";
		return addParameterTemplate;
	}

	
	private String getAddFirstParameterTemplate(String functionName,List<Parameter> newParameters) {
		String addFirstParameterTemplate = "\n\t<!-- Process Add Parameter -->\n\t<xsl:template match=\""
				+ functionName
				+ "\">\n\t  \t<xsl:copy>" ;
				String parameters = "";
				for (Parameter newParameter: newParameters){
					parameters += "\n\t\t\t<" + newParameter.getName() + ">" + newParameter.getValue() + "</"+ newParameter.getName() + ">";
				}
				addFirstParameterTemplate = addFirstParameterTemplate + parameters + "\n\t\t\t<xsl:apply-templates select=\"@*|node()\"/>\n  \t\t</xsl:copy>\n\t</xsl:template>";
		return addFirstParameterTemplate;
	}
	private String getDeleteParameterTemplate(String parameter) {
		String deleteParameterTemplate = "\n\t<!-- Process Delete Parameter -->\n\t<xsl:template match=\"" + parameter + "\"/>\n";
		return deleteParameterTemplate;
	}
	
	private String getDeleteFunctionTemplate(String functionName) {
		String deleteParameterTemplate = "\n\t<!-- Process Delete Parameter -->\n\t<xsl:template match=\"" + functionName + "\"/>\n";
		return deleteParameterTemplate;
	}
	
	private String XSLEndTemplate(){
		String endTemplate = "\n</xsl:stylesheet>";
		return endTemplate;
	}
	

}
